﻿using CleanArchitecture.Core.Configuration;
using CleanArchitecture.Core.Interfaces;
using CleanArchitecture.Infrastructure.Entities.AdminUsers;
using CleanArchitecture.Infrastructure.Entities.Settings;
using CleanArchitecture.Infrastructure.Interfaces;
using CleanArchitecture.Infrastructure.Interfaces.AdminUsers;
using CleanArchitecture.Infrastructure.Interfaces.Authentication;
using CleanArchitecture.Infrastructure.Models;
using CleanArchitecture.Infrastructure.Services.Captcha;
using CleanArchitecture.Web.Backend.BackendApi;
using CleanArchitecture.Web.Factories;
using CleanArchitecture.Web.Validators.AdminUsers;
using FluentValidation.Results;
using Microsoft.AspNetCore.Mvc;

namespace CleanArchitecture.Web.Controllers.Backend.BackendApi
{
    /// <summary>
    /// DavidLee 2019/12/27 通过继承父类Controller将Api调用与Controller渲染
    /// 前端页面分离，保持页面渲染简洁性
    /// 前端页面渲染控制器路由可在RouteProvider中注册，Api Ajax路由由Route Attribute注册
    /// </summary>
    public class BackendLoginApiController : BackendLoginController
    {
        private readonly SecuritySettings _securitySettings;
        private readonly AdminUserSettings _adminuserSettings;
        private readonly CaptchaSettings _captchaSettings;
        private readonly IAuthenticationService _authenticationService;
        private readonly IAdminUserRegistrationService _adminuserReistrationService;
        private readonly IDomainEventDispatcher _eventDispatcher;
        private readonly IWorkContext _workContext;
        public BackendLoginApiController(IAdminUserModelFactory adminusermodelFact,
            SecuritySettings securitySettings,
            AdminUserSettings adminuserSettings,
            CaptchaSettings captchaSettings,
            IAuthenticationService authenticationService,
            IAdminUserRegistrationService adminuserregistrationService,
            IDomainEventDispatcher eventDispatcher,
            IWorkContext workContext)
            : base(adminusermodelFact, securitySettings)
        {
            this._securitySettings = securitySettings;
            this._adminuserSettings = adminuserSettings;
            this._captchaSettings = captchaSettings;
            this._authenticationService = authenticationService;
            this._adminuserReistrationService = adminuserregistrationService;
            this._eventDispatcher = eventDispatcher;
            this._workContext = workContext;
        }
        [HttpPost(BackendApiRouteConfig.LoginApiRoute)]
        public IActionResult Login([FromBody]LoginModel model)
        {
            if (ModelState.IsValid)
            {
                if (_securitySettings.BackendLoginVerifyType.Equals("captcha") && _captchaSettings.Enabled)
                {
                    //Validate CAPTCHA
                    var captcha = new Captcha(_captchaSettings);
                    if (!captcha.ValidateCaptchaCode(model.CaptchaCode, HttpContext))
                        return WarnJson(ApiResponseMessages.CaptchaCodeError);
                }
                string responseMsg = string.Empty;
                LoginValidator validator = new LoginValidator(_adminuserSettings, _securitySettings);
                ValidationResult results = validator.Validate(model);
                if (!results.IsValid)
                {
                    foreach (var failure in results.Errors)
                        responseMsg += failure.ErrorMessage + "\n";

                    return WarnJson(responseMsg);
                }
                var loginUser = _adminuserReistrationService.ValidateAdminUser(model.LoginUser, model.Password);
                var loginResponse = new LoginResultMsg();
                if (loginUser.ExtraInfo is LoginResults && (LoginResults)loginUser.ExtraInfo == LoginResults.Successful)
                {
                    //sign in new adminuser
                    _authenticationService.SignIn(loginUser, model.RememberMe);

                    //raise event    
                    if (_adminuserSettings.LogAdminUserLoggedEvent)
                    {
                        loginUser.SysLogLvl = SystemLogLevel.Information;
                        loginUser.SysLogMsg = $"后台用户：Id: {loginUser.Id}, 登录名: {model.LoginUser}, 成功登录系统。";
                        _eventDispatcher.Dispatch(new AdminUserLoggedEvent(loginUser));
                    }
                    return SuccessJson(loginResponse[LoginResults.Successful]);
                }
                //else 
                return ErrorJson(loginResponse[(LoginResults)loginUser.ExtraInfo]);
            }
            return ErrorJson(ApiResponseMessages.ModelBindingError);
        }

        [HttpPost(BackendApiRouteConfig.LogoutApiRoute)]
        public IActionResult Logout()
        {
            var CurrentUser = _workContext.CurrentAdminUser;
            //standard logout 
            _authenticationService.SignOut();
            //raise event    
            if (_adminuserSettings.LogAdminUserLoggedEvent)
            {
                CurrentUser.SysLogLvl = SystemLogLevel.Information;
                CurrentUser.SysLogMsg = $"后台用户：Id: {CurrentUser.Id}, 用户名: {CurrentUser.UserName}, 退出系统。";
                _eventDispatcher.Dispatch(new AdminUserLoggedEvent(CurrentUser));
            }
            return SuccessJson(ApiResponseMessages.LogoutSuccessful);
        }
    }
}
